package models;

import java.util.*;

import javax.persistence.Entity;
import javax.persistence.OneToMany;

import controllers.CRUD.Hidden;

import play.data.validation.Password;
import play.db.jpa.Model;
import play.libs.Codec;
import play.db.jpa.Blob;

/**
 * 
 * This Model Represents the User that has email, and password to login the
 * system and his/her information i.e. first name, last name, nickname, adress ,
 * age , date of birth, and define whether the user is a system admin or not.
 * 
 * @author Shady
 */
@Entity
public class User extends Model {
	@OneToMany
	public List<Draft> draft;
	@OneToMany
	public List<Label>labels;
	public String email;
	@Password
	public String password;
	@Hidden
	public String passwordHash;
	public String firstName;
	public String lastName;
	public String nickName;
	@Hidden
	public String country;
	public Date dateOfBirth;
	public Blob profilePicture;
	@OneToMany
	 public List<RequestFollower> requests;


	public int age;
	public String address;
	public boolean isAdmin = true;
	public boolean notifyOnOrganization;
	public boolean notifyOnDepartment;
	public boolean notifyOnTopic;
	public boolean notifyOnIdea;
	public boolean notifyOnTag;
	public int views;
	public int communityContribution;

	/**
	 * The constructor that initialize a User instance.
	 * 
	 * @param email
	 *            String
	 * @param password
	 *            String
	 * @param firstname
	 *            String
	 * @param lastName
	 *            String
	 * @param nickName
	 *            String
	 * @param country
	 *            String
	 * @param dateOfBirth
	 *            Date
	 * @param address
	 *            String
	 */
	public User(String email, String password, String firstname,
			String lastName, String nickName, String country, Date dateOfBirth,
			String address) {

		this.email = email;
		this.password = password;
		this.firstName = firstname;
		this.lastName = lastName;
		this.nickName = nickName;
		this.country = country;
		this.dateOfBirth = dateOfBirth;
		this.address = address;
		setPassword(password);
		this.draft = new ArrayList<Draft>();
		updateAge();
		notifyOnOrganization = true;
		notifyOnDepartment = true;
		notifyOnTopic = true;
		notifyOnIdea = true;
		notifyOnTag = true;

	}

	/**
	 * It encrypts the password so that no one can know the password of the User
	 * even the admin.
	 * 
	 * @author Shady
	 * @param password
	 *            String
	 */
	public void setPassword(String password) {
		this.password = password;
		this.passwordHash = Codec.hexMD5(password);
	}

	/**
	 * It checks whether the email and the password combination are for a user
	 * that registered or not
	 * 
	 * @author Shady
	 * @param email
	 *            String
	 * @param password
	 *            String
	 * @return True if the user email and password existed in the database and
	 *         for a valid User, False otherwise.
	 */
	public static boolean isValidLogin(String email, String password) {
		return (count("email=? AND PasswordHash=?", email,
				Codec.hexMD5(password)) == 1);
	}

	/**
	 * It checks whether this email is existed in the database or not.
	 * 
	 * @author Shady
	 * @param email
	 *            String
	 * @return True if the email exists, False otherwise.
	 */
	public static boolean isExist(String email) {
		return (count("email=? ", email) == 1);
	}

	/**
	 * It calculates the age of the user from his/her date of birth.
	 * 
	 * @author Shady
	 */
	public void updateAge() {
		Calendar dob = Calendar.getInstance();
		dob.setTime(dateOfBirth);
		Calendar today = Calendar.getInstance();
		age = today.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
	}

	public static User connect(String email, String password) {
		return User.find("email= ? AND PasswordHash= ?", email,
				Codec.hexMD5(password)).first();
	}

	public String toString() {
		return firstName;
	}

	/**
	 * It Updates the user information.
	 * 
	 * @author Shady
	 * @param email
	 *            String
	 * @param password
	 *            String
	 * @param firstname
	 *            String
	 * @param lastName
	 *            String
	 * @param nickName
	 *            String
	 * @param country
	 *            String
	 * @param dateOfBirth
	 *            Date
	 * @param address
	 *            String
	 */
	public void updateUser(String email, String password, String firstname,
			String lastName, String nickName, String country, Date dateOfBirth,
			String address) {

		this.email = email;
		this.password = password;
		this.firstName = firstname;
		this.lastName = lastName;
		this.nickName = nickName;
		this.country = country;
		this.dateOfBirth = dateOfBirth;
		this.address = address;
		setPassword(password);
		updateAge();
		this.save();

	}
}